var React = require('react');
var ReactDOM = require('react-dom');
var createReactClass = require('create-react-class');
var fs = require('fs');
var path = require('path');

var redux = require('redux');
var createStore = redux.createStore;
var combineReducers = redux.combineReducers;
var redux = require('react-redux')
var Provider = redux.Provider;
var connect = redux.connect;

var InputBar = require('./InputBar.js');
var ConversationList = require('./ConversationList.js');
var ContactList = require('./ContactList.js');
var ChatHistory = require("./ChatHistory.js");

var PeerMessageDB = require('./db/PeerMessageDB.js');
var GroupMessageDB = require('./db/GroupMessageDB.js');
var ConversationDB = require('./db/ConversationDB.js');
var ContactDB = require('./db/ContactDB.js');
var StytemDB = require('./db/StytemDB.js');
var userDB = require('./db/UserDB.js');
var GroupDB = require('./db/GroupDB.js');

var FileCommand = require('./p2pfile/file_command.js');

let shell = require('electron').shell
var remote = require('electron').remote;
var ipc = require('electron').ipcRenderer;
const {dialog} = require('electron').remote
const {BrowserWindow} = require('electron').remote;
const {clipboard} = require('electron')
var path = remote.require('path');
var app = require('electron').remote.app;
var storage = require('electron-storage');
const uuidv1 = remote.require('uuid/v1');
import {HOST, DEBUG, FILE_LIMIT} from './config.js';

var api = require('./api.js');
var CONVERSATION_PEER = "peer";
var CONVERSATION_GROUP = "group";

function setDockBadge(total) {
    console.log("unread count:" + total);
    if (total > 0) {
        ipc.sendSync('set-badge', "" + total);
    } else {
        ipc.sendSync('set-badge', "");
    }
}


var AppContent = createReactClass({
    getInitialState: function() {
        this.im = new IMService();
        this.im.observer = this;
        return {
            inDrag:0,
            showContact:false,
            showGroupContact:false,
            showConversation:true,
            showPreview:false,
            showUserList:false,
            preview:{},
            contacts:[],
            contact:{},
            contactsGroups:[],
            systemMessage:[]
        };
    },


    componentWillMount: function() {
        this.channels = [];
        this.declinedChannels = [];
        this.uploadingMessages = [];

        window.addEventListener('online',  this.onOnline);
        window.addEventListener('offline',  this.onOffline);

        storage.isPathExists("sync.json")
                .then((exists) => {
                    if (exists) {
                        return storage.get("sync.json");
                    } else {
                        return {};
                    }
                })
                .then((data) => {
                    this.syncKeys = data;
                })
                .then(() => {
                    return storage.get("token.json")
                })
               .then(data => {
                   //todo check token
                   return data;
               })
               .then((data) => {
                    var loginUser = data;
                    this.props.dispatch({type:"set_login_user", loginUser:loginUser});
                    api.token = data.gobelieveToken;
                    api.accessToken = data.accessToken

                    this.loadData(data);
               })
               .then(() => {
                    this.checkVersion();
               });

    },

    componentDidMount: function() {
        var platform;
        if (process.platform == 'darwin') {
            platform = "osx";
        } else {
            platform = "win";
        }
    },

    componentWillUnmount: function() {
        window.removeEventListener('online',  this.onOnline);
        window.removeEventListener('offline',  this.onOffline);
    },


    onOnline: function() {
        console.log("online");

    },

    onOffline: function() {
        console.log("offline");
        this.im.stop();
        var self = this;
        setTimeout(function() {
            self.im.start();
        }, 0);
    },

    checkVersion: function() {
        api.getVersion()
        .then((r) => {
            console.log("latest version:", r);
            var ver = app.getVersion();
            var arr = ver.split(".");
            var major = parseInt(arr[0]);
            var minor = parseInt(arr[1]);
            var build = parseInt(arr[2]);

            var url = r['url'];
            var newVersion = false;
            if (r['major'] > major) {
                newVersion = true;
            } else if (r['major'] >= major && r['minor'] > minor) {
                newVersion = true;
            } else if (r['major'] >= major && r['minor'] >= minor && r['build'] > build) {
                newVersion = true;
            }

            if (newVersion) {
                var options = {
                    message: `发现新版本,是否要升级？`,
                    buttons: ["确定", "取消"],
                    defaultId: 0,
                    cancelId: 1
                };
                var self = this;
                var win = remote.getCurrentWindow();
                dialog.showMessageBox(win, options, function(response) {
                    if (response == 1) {
                        return;
                    }
                    shell.openExternal(url);
                });
            }
        }, (err) => {
            console.warn();
            ("err:", err);
        });
    },

    syncContacts:function() {
        return api.getFriends()
                  .then((res) => {
                      console.log("friends:", res);
                      res.friends.forEach(function(f) {
                          f.uid = parseInt(f.im_uid);
                          f.name = f.nickname;
                          f.avatar = f.portrait;
                      });

                      var contacts = [...this.state.contacts];

                      for (var i in res.friends) {
                          var c = res.friends[i];

                          var index = contacts.findIndex(function(item) {
                              return item.uid == c.uid
                          });
                          if (index != -1) {
                              console.log("update contact:", c)
                              this.contactDB.update(c);
                              contacts[index] = c;
                          } else {
                              console.log("add contact:", c);
                              this.contactDB.add(c);
                              contacts.push(c);
                          }
                      }

                      for (var i in contacts) {
                          var contact = contacts[i];
                          userDB.addUser(contact);
                      }

                      var conversations = this.props.conversations;
                      var newConvs = conversations.map((c) => {
                          if (c.type == CONVERSATION_PEER) {
                              var t = contacts.find((contact)=> {
                                  return (contact.uid == c.peer);
                              });
                              if (t) {
                                  c.name = t.name || "" + t.uid;
                                  c.avatar = t.avatar;
                              }
                          }
                          return c;
                      });
                      this.props.dispatch({type:"set_conversations", conversations:newConvs});
                      this.setState({contacts:res.friends});
                      return contacts;
                  })
                  .catch((err) => {
                      console.log("error:", err);
                  });
    },

    loadData: function(tokenData) {
        var self = this;
        var uid = this.props.loginUser.uid;
        var token = this.props.loginUser.accessToken;
        var gobelieveToken = this.props.loginUser.gobelieveToken;
        console.log("token:", token, gobelieveToken, uid);

        this.uptime = Math.ceil(new Date().getTime()/1000);

        var filename = path.join(app.getPath("userData"), "peer_messages_" + uid + ".db");
        console.log("peer message db file name:" + filename);
        this.imDB = new PeerMessageDB(filename);

        filename = path.join(app.getPath("userData"), "group_messages_" + uid + ".db");
        console.log("group message db file name:" + filename);
        this.groupMessageDB = new GroupMessageDB(filename);

        filename = path.join(app.getPath("userData"), "conversations_" + uid + ".db");
        console.log("conversation db file name:" + filename);
        this.conversationDB = new ConversationDB(filename);

        filename = path.join(app.getPath("userData"), "contacts_" + uid + ".db");
        this.contactDB = new ContactDB(filename);

        filename = path.join(app.getPath("userData"), "groups_" + uid + ".db");
        this.groupDB = new GroupDB(filename);

        filename = path.join(app.getPath("userData"), "stytem_" + uid + ".db");
        this.stytemDB = new StytemDB(filename);

        this.im.host = HOST;
        this.im.accessToken = gobelieveToken;
        if (this.syncKeys.messageSyncKey) {
            this.im.syncKey = this.syncKeys.messageSyncKey;
        }
        this.stytemDB.load().then((contacts)=>{
            console.log(contacts)
            if(contacts.length > 0){
                for(var i=0;i<contacts.length;i++){
                    this.setState({
                        systemMessage:contacts[i]
                    })
                }
            }
        })
        storage.get("token.json")
        .then(data => {
            this.setState({info:data})
        });
        api.getAllGroup()
                .then((group) => {
                    this.setState({contactsGroups:group});
                });
        this.contactDB.load()
            .then((contacts) => {
                contacts = contacts.filter(function(c) {
                    return !c.deleted
                });
                console.log("contacts:", contacts);
                for (var i in contacts) {
                    var contact = contacts[i];
                    userDB.addUser(contact);
                }
                
                this.setState({contacts:contacts});
            })
            .then(() => {
                return this.conversationDB.getConversationList();
            })
            .then((convs) => {
                var convs = convs.map(function(c) {
                    if (c.type == CONVERSATION_PEER) {
                        var u = userDB.findUser(c.peer);
                        if (u) {
                            c.name = u.name || "" + u.uid;
                            c.avatar = u.avatar;
                        } else {
                            c.name = "" + c.peer;
                            c.avatar = "";
                        }
                    } else if (c.type == CONVERSATION_GROUP) {
                        c.dirty = true;//群组信息在点击群组会话时更新
                        self.groupDB.findGroup(c.groupID)
                                    .then((group) => {
                                        if (group) {
                                            self.props.dispatch({type:"set_conversation_name", name:group.name, avatar:group.portrait, cid:c.cid,lvl:group.lvl});
                                        } else {
                                            //更新群组信息
                                            api.getGroup(c.groupID)
                                            .then((group) => {
                                                console.log("add group:", group);
                                                self.groupDB.addGroup(group);
                                                var action = {
                                                    type:"set_conversation_name",
                                                    lvl:group.lvl, 
                                                    name:group.name, 
                                                    avatar:group.portrait, 
                                                    cid:c.cid
                                                };
                                                self.props.dispatch(action);
                                                self.props.dispatch({type:"set_conversation_dirty", cid:c.cid, dirty:false});
                                            })
                                            .catch((err) => {
                                                console.log("get group err:", err);
                                            });
                                        }
                                    });
                    }
                    return c;
                });

                convs.sort(function(a, b) {
                    var t2 = b.message ? b.message.timestamp : 0;
                    var t1 = a.message ? a.message.timestamp : 0;
                    return (t2 - t1);
                });
                console.log(convs)
                this.props.dispatch({type:"set_conversations", conversations:convs});
                this.im.start();
            })
            .then(() => {
                return this.syncContacts();
            })
            .catch((err) => {
                console.log("err:", err);
            });
    },

    showNotification: function(title, body) {
        // Let's check if the browser supports notifications
        if (!("Notification" in window)) {
            console.log("This browser does not support desktop notification");
        }

        var options = {
            body:body,
        };

        var notification = new Notification(title, options);
        notification.onclick = function() {
            console.log("notification on click");
        };
    },

    showMessageNotification: function(msg) {
        var u = userDB.findUser(msg.sender);
        var title = ""
        if (u && u.name) {
            console.log("u name:" + u.name);
            title = u.name;
        } else {
            title = "" + msg.sender;
        }
        var content = "";
        if (msg.contentObj.text) {
            content = msg.contentObj.text;
        } else if (msg.contentObj.audio) {
            content = "[语音]";
        } else if (msg.contentObj.image ||
                   msg.contentObj.image2) {
            content = "[图片]";
        } else if (msg.contentObj.file) {
            content = "[文件]";
        } else {
            return;
        }

        this.showNotification(title, content);
    },

    removeUploadRequest: function(uploadReq) {
        var index = this.uploadingMessages.indexOf(uploadReq);
        if (index == -1) {
            return;
        }

        this.uploadingMessages.splice(index, 1);
    },

    sendTextMessage:function(text) {
        var now = new Date();
        var obj = {"text": text, "uuid":uuidv1()};
        var textMsg = JSON.stringify(obj);

        var db;
        var message;
        var conv = this.props.conversation;
        if (conv.type == CONVERSATION_PEER) {
            message = {
                peer: this.props.conversation.peer,
                sender: this.props.loginUser.uid,
                receiver: this.props.conversation.peer,
                content: textMsg,
                timestamp: (now.getTime() / 1000),
                contentObj: obj,
            };
            db = this.imDB;
        } else if (conv.type == CONVERSATION_GROUP) {
            message = {
                groupID: this.props.conversation.groupID,
                sender: this.props.loginUser.uid,
                receiver: this.props.conversation.groupID,
                content: textMsg,
                timestamp: (now.getTime() / 1000),
                contentObj: obj,
            };
            db = this.groupMessageDB;
        } else {
            return;
        }

        if (this.im.connectState == IMService.STATE_CONNECTED) {
            db.saveMessage(message, () => {
                this.conversationDB.setLatestMessage(conv.cid, message);
                this.props.dispatch({type:"set_latest_message",
                                     message:message,
                                     conversation:conv});
                if (this.im.connectState == IMService.STATE_CONNECTED) {
                    if (conv.type == CONVERSATION_PEER) {
                        this.im.sendPeerMessage(message);
                    } else if (conv.type == CONVERSATION_GROUP) {
                        this.im.sendGroupMessage(message);
                    }
                } else {
                    message.error = true;
                    db.setError(message.msgLocalID, true);
                }
                if (this.chat) {
                    this.chat.getWrappedInstance().addMessage(message);
                }

                this.inputBar.clear();
            });
        }
    },

    sendImageMessage: function(b64, w, h) {
        var now = new Date();
        var uuid = uuidv1();
        var obj = {
            "image2": {
                url: b64,
                width: w,
                height: h
            },
            "uuid":uuid
        };

        var db;
        var msg;
        var conv = this.props.conversation;

        if (this.props.conversation.type == CONVERSATION_PEER) {
            var msg = {
                peer: this.props.conversation.peer,
                sender: this.props.loginUser.uid,
                receiver: this.props.conversation.peer,
                content: JSON.stringify(obj),
                timestamp: (now.getTime() / 1000)
            };
            msg.contentObj = obj;
            db = this.imDB;
        } else if (conv.type == CONVERSATION_GROUP) {
            var msg = {
                groupID: this.props.conversation.groupID,
                sender: this.props.loginUser.uid,
                receiver: this.props.conversation.groupID,
                content: JSON.stringify(obj),
                timestamp: (now.getTime() / 1000)
            };
            msg.contentObj = obj;
            db = this.groupMessageDB;
        } else {
            return;
        }

        db.saveMessage(msg)
            .then((msg) => {
                this.conversationDB.setLatestMessage(conv.cid, msg);
                this.props.dispatch({
                    type: "set_latest_message",
                    message: msg,
                    conversation: conv
                });
                if (this.chat) {
                    this.chat.getWrappedInstance().addMessage(msg);
                }
                return api.uploadImage(b64)
            })
            .then((url) => {
                var obj = {
                    "image2": {
                        url: url,
                        width: w,
                        height: h
                    },
                    "uuid":uuid
                };
                msg.content = JSON.stringify(obj);
                msg.contentObj = obj;
                if (this.im.connectState == IMService.STATE_CONNECTED) {
                    if (conv.type == CONVERSATION_PEER) {
                        this.im.sendPeerMessage(msg);
                    } else if (conv.type == CONVERSATION_GROUP) {
                        this.im.sendGroupMessage(msg);
                    }
                } else {
                    msg.error = true;
                    db.setError(msg.msgLocalID, true);
                    if (this.chat) {
                        this.chat.getWrappedInstance().setMessageError(msg.msgLocalID, true);
                    }
                }
                db.updateContent(msg.msgLocalID, msg.content, msg.contentObj);
            })
            .catch((err) => {
                console.log('error:', err);
                db.setError(msg.msgLocalID, true);
                if (this.chat) {
                    this.chat.getWrappedInstance().setMessageError(msg.msgLocalID, true);
                }
            });
    },

    sendFileMessage: function(filePath, size) {
        var now = new Date();
        var filename = path.basename(filePath);
        var uuid = uuidv1();
        var obj = {
            file: {
                path: filePath,
                filename: filename,
                size: size
            },
            uuid:uuid
        }
        var msg;
        var db;
        var cid = this.props.conversation.cid;
        var type = this.props.conversation.type;
        var conv = this.props.conversation;

        if (this.props.conversation.type == CONVERSATION_PEER) {
            msg = {
                peer: this.props.conversation.peer,
                sender: this.props.loginUser.uid,
                receiver: this.props.conversation.peer,
                content: JSON.stringify(obj),
                timestamp: (now.getTime() / 1000),

            };
            msg.contentObj = obj;
            db = this.imDB;
        } else if (this.props.conversation.type == CONVERSATION_GROUP) {
            msg = {
                groupID: this.props.conversation.groupID,
                sender: this.props.loginUser.uid,
                receiver: this.props.conversation.groupID,
                content: JSON.stringify(obj),
                timestamp: (now.getTime() / 1000)
            };
            msg.contentObj = obj;
            db = this.groupMessageDB;
        } else {
            return;
        }

        db.saveMessage(msg, () => {
            msg.uploading = true;
            msg.progress = 0;
            this.conversationDB.setLatestMessage(cid, msg);
            this.props.dispatch({
                type: "set_latest_message",
                message: msg,
                conversation: conv
            });
            if (this.chat) {
                this.chat.getWrappedInstance().addMessage(msg);
            }
            var uploadReqest = {
                msgLocalID: msg.msgLocalID,
                progress: 0,
                cid: conv.cid,
                conversationType: conv.type,
            };
            api.uploadFile(filename, filePath,
                (progress) => {
                    console.log("upload file progress:", progress);
                    uploadReqest.progress = progress;
                    if (this.chat && cid == this.props.conversation.cid) {
                        this.chat.getWrappedInstance().setMessageUploadProgress(msg.msgLocalID, progress);
                    }
                },
                (url) => {
                    console.log("uploaded file url:", url);
                    var obj = {
                        file: {
                            filename: filename,
                            size: size,
                            url: url
                        },
                        uuid:uuid
                    };
                    if (this.im.connectState == IMService.STATE_CONNECTED) {
                        msg.content = JSON.stringify(obj);
                        if (type == CONVERSATION_PEER) {
                            this.im.sendPeerMessage(msg);
                        } else if (type == CONVERSATION_GROUP) {
                            this.im.sendGroupMessage(msg);
                        }
                    } else {
                        msg.error = true;
                        db.setError(msg.msgLocalID, true);
                    }
                    obj.file.path = filePath;
                    msg.contentObj = obj;
                    msg.content = JSON.stringify(obj);
                    db.updateContent(msg.msgLocalID, msg.content, msg.contentObj);
                    if (this.chat) {
                        this.chat.getWrappedInstance().setMessageUploadComplete(msg.msgLocalID);
                    }
                    this.removeUploadRequest(uploadReqest);
                },
                (err) => {
                    console.log('error:', e);
                    db.setError(msg.msgLocalID, true);
                    if (this.chat) {
                        this.chat.getWrappedInstance().setMessageError(msg.msgLocalID, true);
                    }
                    this.removeUploadRequest(uploadReqest);
                })
                .then((req) => {
                    uploadReqest.request = req;
                    this.uploadingMessages.push(uploadReqest);
                });
        });

    },


    startCapture: function(target) {
        var oldImage = clipboard.readImage();
        var oldB64;
        if (oldImage) {
            oldB64 = oldImage.toDataURL();
        }

        console.log("old image:", oldB64);
        var self = this;
        capture.captureScreen()
               .then((code) => {
                   console.log("resolve code:" + code);
                   if (code != 0) {
                       return;
                   }
                   var temp = clipboard.readImage();
                   if (temp) {
                       var size = temp.getSize();
                       var b64 = temp.toDataURL();
                       self.setState({
                           showPreview:true,
                           preview:{url:b64, width:size.width, height:size.height},
                       })
                       console.log("image:", b64);
                       if (b64 != oldB64) {
                           //this.sendImageMessage(b64);
                       }
                   }
               }, function (code) {
                   console.log("reject code:" + code);
               });
    },

    openFileReceiveWindow: function(uid, peer, token, channelID, isCaller, filePath, fileName, fileSize) {
        var index = this.channels.findIndex(function(item) {
            return (item == channelID);
        })
        if (index != -1) {
            return;
        }
        this.channels.push(channelID);

        var u = userDB.findUser(peer);
        var name = u ? u.name : ("" + peer);
        var options = {
            message:`${name}发来文件${fileName}`,
            buttons:["保存", "拒绝"],
            defaultId:0,
            cancelId:1
        };
        var self = this;
        var win = remote.getCurrentWindow();
        dialog.showMessageBox(win, options, function(response) {
            if (response == 1) {
                self.declinedChannels.push(channelID);
                return;
            }
            self.openFileWindow(uid, peer, token, channelID, false, filePath, fileName, fileSize);
        });
    },

    openFileWindow: function(uid, peer, token, channelID, isCaller, filePath, fileName, fileSize) {
        var name = "";
        var avatar = ""
        var u = userDB.findUser(peer);
        if (u) {
            name = encodeURIComponent(u.name);
            avatar = encodeURIComponent(u.avatar);
        }
        if (filePath) {
            filePath = encodeURIComponent(filePath);
        }

        var options = {
            width:480,
            height:180,
            maxWidth:640,
            maxHeight:320,
            minWidth:420,
            minHeight:120,
        };

        var self = this;
        var win = new BrowserWindow(options);

        win.on('closed', () => {
            console.log("file window close");
        })
        //under 2000
        var url = `file://${__dirname}/p2pfile/file.html?uid=${uid}&token=${token}&peer=${peer}&channel=${channelID}&is_caller=${isCaller}&file_size=${fileSize}`;
        if (name) {
            url = url + `&name=${name}`;
        }
        if (avatar) {
            url = url + `&avatar=${avatar}`;
        }
        if (filePath) {
            url = url + `&file_path=${filePath}`;
        }
        if (fileName) {
            url = url + `&file_name=${fileName}`;
        }

        win.loadURL(url);
        if (DEBUG) {
            win.webContents.openDevTools();
        }
    },

    //voip
    openVOIPWindow: function(uid, peer, token, accessToken, channelID, is_caller, is_video) {
        if (this.voipWin || this.groupCallWin) {
            return;
        }
        var index = this.channels.findIndex(function(item) {
            return (item == channelID);
        })
        if (index != -1) {
            return;
        }

        var name = "";
        var avatar = ""
        var u = userDB.findUser(peer);
        if (u) {
            name = encodeURIComponent(u.name);
            avatar = encodeURIComponent(u.avatar);
        }
        var options = {
            width:320,
            height:480,
            minWidth:320,
            minHeight:480,
            maxWidth:400,
            maxHeight:600,
            maximizable:false,
            resizable:true,
        };

        if (process.platform == 'darwin') {
            options.titleBarStyle = 'hidden';
        }

        var self = this;
        var win = new BrowserWindow(options);

        win.on('closed', () => {
            win = null
            self.voipWin = null;
            console.log("voip window close");
        })
        var url;
        if (is_video) {
            url = `file://${__dirname}/voip/voip.html?uid=${uid}&token=${token}&access_token=${accessToken}&peer=${peer}&channel=${channelID}&is_caller=${is_caller}&is_video=${is_video}`;
        } else {
            url = `file://${__dirname}/voip/voip_voice.html?uid=${uid}&token=${token}&access_token=${accessToken}&peer=${peer}&channel=${channelID}&is_caller=${is_caller}&is_video=${is_video}`;
        }
        if (name) {
            url = url + `&name=${name}`;
        }
        if (avatar) {
            url = url + `&avatar=${avatar}`;
        }
        win.loadURL(url);
        if (DEBUG) {
            win.webContents.openDevTools();
        }
        this.voipWin = win;
        this.channels.push(channelID);
    },

    //group call
    openGroupCallWindow: function(uid, name, token, room, initiator, participants, groupID) {
        if (this.groupCallWin || this.voipWin) {
            return;
        }
        var index = this.channels.findIndex(function(item) {
            return (item == room);
        })

        if (index != -1) {
            return;
        }

        participants = participants.map(function(p) {
            var u = userDB.findUser(p);
            var obj = {
                id:p,
                uid:p,
                name:u ? u.name : "",
                avatar: u ? u.avatar : ""
            };
            return obj;
        });

        var call = {
            uid: uid,
            userName: name,
            room: room,
            initiator: initiator,
            participants: participants,
            groupID: groupID,
        };
        return storage.set("group_call.json", call)
            .then(() => {
                if (this.groupCallWin || this.voipWin) {
                    return;
                }
                var win = new BrowserWindow({
                    width: 800,
                    height: 600,
                    minWidth: 800,
                    minHeight: 600
                });
                win.on('closed', () => {
                    win = null;
                    this.groupCallWin = null;
                    console.log("group call window close");
                })
                win.loadURL(`file://${__dirname}/group_call/group_call.html?token=${token}`);
                if (DEBUG) {
                    win.webContents.openDevTools();
                }
                this.groupCallWin = win;
                this.channels.push(room);
            });
    },

    openVideoWindow: function(videoURL) {
        if (this.videoWin) {
            this.videoWin.close();
            console.log("close video window");
            this.videoWin = undefined;
        }

        videoURL = encodeURIComponent(videoURL);
        var options = {
            width:320,
            height:480,
            minWidth:320,
            minHeight:480,
            maxWidth:400,
            maxHeight:600,
            maximizable:false,
            resizable:true,
        };

        var self = this;
        var win = new BrowserWindow(options);

        win.on('closed', (event) => {
            win = null;
            if ((event.sender == self.videoWin)) {
                self.videoWin = null;
            }
            console.log("video window closed");
        })
        var url = `file://${__dirname}/video.html?video=${videoURL}`;
        win.loadURL(url);
        if (DEBUG) {
            win.webContents.openDevTools();
        }
        this.videoWin = win;
    },

    handlePeerMessage: function (msg) {
        console.log("msg sender:", msg.sender, " receiver:", msg.receiver, " content:", msg.content, " timestamp:", msg.timestamp);

        try {
            msg.contentObj = JSON.parse(msg.content)
        } catch (e) {
            console.log("json parse exception:", e);
            return
        }

        if (msg.contentObj.secret || msg.contentObj.p2p_session) {
            //过滤掉点对点加密消息
            return;
        }

        if (msg.sender != this.props.loginUser.uid) {
            if (player.paused) {
                console.log("play.....");
                player.play();
            } else {
                console.log("player is playing...");
            }
            msg.peer = msg.sender;
        } else {
            //收到自己在其他端发出去的消息
            msg.ack = true;
            msg.peer = msg.receiver;
        }

        var cid = "peer_" + msg.peer;

        this.imDB.saveMessage(msg, () =>  {
            if (this.props.conversation.cid == cid) {
                if (this.chat) {
                    this.chat.getWrappedInstance().addMessage(msg);
                }
            }
            var index = this.props.conversations.findIndex(function(c) {
                return (c.cid == cid);
            });
            var conv = null;
            if (index == -1) {
                var name = "";
                var avatar = "";
                var u = userDB.findUser(msg.peer);
                if (u) {
                    name = u.name;
                    avatar = u.avatar;
                }
                conv = {
                    type:CONVERSATION_PEER,
                    peer:msg.peer,
                    cid:cid,
                    message:msg,
                    unread:0,
                    name:name,
                    avatar:avatar,
                };
                this.conversationDB.addConversation(conv);
                this.props.dispatch({type:"add_conversation", conversation:conv});
            } else {
                conv = this.props.conversations[index];
                this.conversationDB.setLatestMessage(cid, msg);
            }

            this.conversationDB.setLatestMessage(cid, msg);
            this.props.dispatch({type:"set_latest_message",
                                 message:msg,
                                 conversation:conv});

            var win = remote.getCurrentWindow();
            if ((!win.isVisible() || !win.isFocused() || cid != this.props.conversation.cid) &&
                msg.sender != this.props.loginUser.uid) {
                this.showMessageNotification(msg);

                var index = this.props.conversations.findIndex(function(c) {
                    return c.cid == cid;
                });
                if (index != -1) {
                    var unread = this.props.conversations[index].unread + 1;
                    this.props.dispatch({type:"set_unread", cid:cid, unread:unread});
                    this.conversationDB.setNewCount(cid, unread);

                    var total = 0;
                    this.props.conversations.forEach(function(c) {
                        total = total + c.unread;
                    });
                    setDockBadge(total);
                }
            }
        });
    },

    handleMessageACK: function (msg) {
        var msgLocalID = msg.msgLocalID;
        var uid = msg.receiver;
        var cid = "peer_" + uid;
        this.imDB.ackMessage(msgLocalID);
        if (this.props.conversation.cid == cid) {
            if (this.chat) {
                this.chat.getWrappedInstance().ackMessage(msgLocalID);
            }
        }
        console.log("message ack local id:", msgLocalID, " uid:", uid);
    },

    handleMessageFailure: function (msg) {
        var msgLocalID = msg.msgLocalID;
        var uid = msg.receiver;
        var cid = "peer_" + uid;

        console.log("message fail local id:", msgLocalID, " uid:", uid);
        this.imDB.setError(msg.msgLocalID, true);
        if (this.props.conversation.cid == cid) {
            if (this.chat) {
                this.chat.getWrappedInstance().setMessageError(msgLocalID, true);
            }
        }
    },

    handleSystemMessage: function (msg) {
        console.log("system message:", msg);
        var msgs=JSON.parse(msg)
        this.setState({
            systemMessage:msgs
        })
        // var msgs = JSON.parse(msg)
        if(msgs.action == "ADD_FRIEND_REQUEST"){
            this.stytemDB.add(msgs)
        }   
    },

    handleGroupMessage: function (msg) {
        console.log("group msg sender:", msg.sender, " receiver:", msg.receiver, " content:", msg.content, " timestamp:", msg.timestamp);
        var groupID = msg.receiver;
        var cid = "group_" + groupID;

        var index = this.props.conversations.findIndex((c) => {
            return (c.cid == cid);
        });

        if (index == -1) {
            this.groupDB.findGroup(groupID)
                .then((group) => {
                    if (group) {
                        this.props.dispatch({type:"set_conversation_name", name:group.name, avatar:group.portrait, cid:cid,lvl:group.lvl});
                    } else {
                        return api.getGroup(groupID)
                                  .then((group) => {
                                      this.groupDB.addGroup(group);
                                      this.props.dispatch({type:"set_conversation_name",
                                                           name:group.name,
                                                           lvl:group.lvl,
                                                           avatar:group.portrait,
                                                           cid:cid});

                                      if (self.props.conversation.type == CONVERSATION_GROUP &&
                                          self.props.conversation.groupID == group.id) {
                                          group.members.forEach((item)=> {
                                              if (!item.name) {
                                                  var u = userDB.findUser(item.uid);
                                                  if (u) {
                                                      item.name = u.name;
                                                  }
                                              }
                                          })
                                          self.setState({group:group});
                                      }
                                  })
                                  .catch((err) => {
                                    console.log("get group err:", err);
                                  });
                    }
                })
        }

        try {
            msg.contentObj = JSON.parse(msg.content)
        } catch (e) {
            console.log("json parse exception:", e);
            return
        }

        if (msg.sender != this.props.loginUser.uid) {
            if (player.paused) {
                player.play();
            }
            msg.outgoing = false;
        } else {
            //收到自己在其他端发出去的消息
            msg.ack = true;
            msg.outgoing = true;
        }


        this.groupMessageDB.saveMessage(msg, () =>  {
            this.conversationDB.setLatestMessage(cid, msg);

            if (this.props.conversation.cid == cid) {
                if (this.chat) {
                    this.chat.getWrappedInstance().addMessage(msg);
                }
            }

            var index = this.props.conversations.findIndex(function(c) {
                return c.cid == cid;
            })

            var conv = null;
            if (index == -1) {
                var name = ""+groupID;
                conv = {
                    groupID:groupID,
                    type:CONVERSATION_GROUP,
                    cid:cid,
                    message:msg,
                    unread:0,
                    name:name
                };

                this.conversationDB.addConversation(conv);
                this.props.dispatch({type:"add_conversation", conversation:conv});
            } else {
                conv = this.props.conversations[index];
            }

            this.conversationDB.setLatestMessage(cid, msg);
            this.props.dispatch({type:"set_latest_message",
                                 message:msg,
                                 conversation:conv});

            var win = remote.getCurrentWindow();
            if ((!win.isFocused() || cid != this.props.conversation.cid) &&
                msg.sender != this.props.loginUser.uid) {
                this.showMessageNotification(msg);

                var index = this.props.conversations.findIndex(function(c) {
                    return c.cid == cid;
                });

                if (index != -1) {
                    var unread = this.props.conversations[index].unread + 1;
                    this.props.dispatch({type:"set_unread", cid:cid, unread:unread});
                    this.conversationDB.setNewCount(cid, unread);

                    var total = 0;
                    this.props.conversations.forEach(function(c) {
                        total = total + c.unread;
                    });
                    setDockBadge(total);
                }
            }
        });
    },

    handleGroupMessageACK: function (msg) {
        var msgLocalID = msg.msgLocalID;
        var groupID = msg.receiver;
        var cid = "group_" + groupID;

        this.groupMessageDB.ackMessage(msgLocalID);
        if (this.props.conversation.cid == cid) {
            if (this.chat) {
                this.chat.getWrappedInstance().ackMessage(msgLocalID);
            }
        }
        console.log("message ack local id:", msgLocalID, " groupID:", groupID);
    },

    handleGroupMessageFailure: function (msg) {
        var msgLocalID = msg.msgLocalID;
        var groupID = msg.receiver;
        var cid = "group_" + groupID;
        console.log("message fail local id:", msgLocalID, " groupID:", groupID);

        this.groupMessageDB.setError(msg.msgLocalID, true);

        if (this.props.conversation.cid == cid) {
            if (this.chat) {
                this.chat.getWrappedInstance().setMessageError(msgLocalID, true);
            }
        }
    },

    handleGroupNotification: function (nm) {
        console.log("group notification:", JSON.parse(nm));
        try {
            var element = JSON.parse(nm);

            var self = this;
            var groupID;
            var groupName;
            var timestamp;
            var contentObj;

            if (element.create) {
                var obj = element.create;

                groupName = obj.name;
                groupID = obj.group_id;
                timestamp = obj.timestamp;
                if (obj.master == this.props.loginUser.uid) {
                    contentObj = {notification:`您创建了${obj.name}群组`}
                } else {
                    contentObj = {notification:`您加入了${obj.name}群组`}
                }
            } else if (element.add_member) {
                var obj = element.add_member;
                groupID = obj.group_id;
                timestamp = obj.timestamp;
                contentObj = {notification:`${obj.name}加入群组`}
            } else if (element.quit_group) {
                var info = this.state.info;
                var obj = element.quit_group;
                var id="group_"+obj.group_id
                if(info.name == obj.name){
                    this.deleteConversation(id)
                    //  api.getAllGroup()
                    //     .then((group) => {
                    //         this.setState({contactsGroups:group});
                    //     });
                    return false;
                }else{
                    groupID = obj.group_id;
                    timestamp = obj.timestamp;
                    var name;
                    if (obj.name) {
                        name = obj.name;
                    } else {
                        var u = userDB.findUser(obj.member_id);
                        if (u) {
                            name = u.name;
                        } else {
                            name = obj.member_id;
                        }
                    }
                    contentObj = {notification:`${name}离开群组`};
                }
            } else if (element.update_name) {
                var obj = element.update_name;
                groupID = obj.group_id;
                timestamp = obj.timestamp;
                contentObj = {notification:`群组改名为${obj.name}`}
            }
            //  else if (element.update_group_bulletin) {
            //     var obj = element.update_group_bulletin;
            //     groupID = parseInt(obj.group.id);
            //     timestamp = obj.timestamp/1000;
            //     contentObj = {notification:`${obj.user.nickname}修改群公告为:${obj.group.bulletin}`}
            // } 
            else if(element.disband){
                var obj = element.disband;
                var id="group_"+obj.group_id;
                this.deleteConversation(id);
                return false;
            }
            else {
                return;
            }
         
            var cid = "group_" + groupID;
            
            var msg = {
                groupID:groupID,
                receiver:groupID,
                sender:0,
                timestamp:timestamp,
                contentObj:contentObj,
                content:nm
            };
            
            this.groupMessageDB.saveMessage(msg, () =>  {
             
                if (this.props.conversation.cid == cid) {
                    if (this.chat) {
                        this.chat.getWrappedInstance().addMessage(msg);
                    }
                }

                var index = this.props.conversations.findIndex((item) => {
                    return item.cid == cid;
                });

                var conv = null;
                if (index == -1) {
                    var name = groupName || ""+groupID;
                    conv = {
                        groupID:groupID,
                        type:CONVERSATION_GROUP,
                        cid:cid,
                        message:msg,
                        unread:0,
                        name:name
                    };

                    this.conversationDB.addConversation(conv);
                    this.props.dispatch({type:"add_conversation", conversation:conv});
                } else {
                    conv = this.props.conversations[index];
                    this.conversationDB.setLatestMessage(cid, msg);
                    this.props.dispatch({type:"set_latest_message", message:msg, conversation:conv});
                }

                api.getGroup(groupID)
                    .then((group) => {
                        console.log("get group:", group);
                        self.groupDB.addGroup(group);
                        self.props.dispatch({
                            type: "set_conversation_name",
                            name: group.name,
                            avatar: group.portrait,
                            lvl:group.lvl,
                            cid: cid
                        });
                        if (self.props.conversation.type == CONVERSATION_GROUP &&
                            self.props.conversation.groupID == group.id) {
                            group.members.forEach((item)=> {
                                if (!item.name) {
                                    var u = userDB.findUser(item.uid);
                                    if (u) {
                                        item.name = u.name;
                                    }
                                }
                            })
                            self.setState({
                                group: group
                            });
                        }
                    })
                    .catch((err) => {
                        console.log("get group err:", err);
                    });

            });


        } catch (e) {
            console.log("json parse exception:", e);
            return
        }
    },

    handleRTMessage: function(msg) {
        console.log("rt message...:", msg.content);
        var uid = this.props.loginUser.uid;
        var gobelieveToken = this.props.loginUser.gobelieveToken;
        var accessToken = this.props.loginUser.accessToken;

        if (msg.receiver != uid) {
            return;
        }

        var rtObj = JSON.parse(msg.content);
        if (rtObj.voip) {
            var obj = rtObj.voip;
            var cmd = new VOIPCommand();
            cmd.fromData(obj);
            if (cmd.cmd == VOIPCommand.VOIP_COMMAND_DIAL) {
                this.openVOIPWindow(uid, msg.sender, gobelieveToken, accessToken, cmd.channelID, false, false);
            } else if (cmd.cmd == VOIPCommand.VOIP_COMMAND_DIAL_VIDEO) {
                this.openVOIPWindow(uid, msg.sender, gobelieveToken, accessToken, cmd.channelID, false, true);
            }
        } else if (rtObj.conference) {
            if (rtObj.conference.command == "invite") {
                var name = this.props.loginUser.name;
                this.openGroupCallWindow(uid, name, gobelieveToken,
                    rtObj.conference.channel_id,
                    rtObj.conference.initiator,
                    rtObj.conference.participants,
                    rtObj.conference.group_id);
            }
        } else if (rtObj.file) {
            var cmd = new FileCommand();
            cmd.fromData(rtObj.file);
            if (cmd.cmd == FileCommand.VOIP_COMMAND_DIAL) {
                if (!cmd.channelID || !cmd.name || !cmd.size) {
                    return;
                }
                var index = this.declinedChannels.findIndex(function(item) {
                    return item == cmd.channelID;
                });
                if (index == -1) {
                    //表示文件的接受者在线
                    var command = new FileCommand();
                    command.cmd = FileCommand.VOIP_COMMAND_PRESENT;
                    command.channelID = cmd.channelID;
                    var presentMsg = {};
                    presentMsg.sender = msg.receiver;
                    presentMsg.receiver = msg.sender;
                    presentMsg.content = JSON.stringify({file:command.toData()});
                    this.im.sendRTMessage(presentMsg);
                } else {
                    var command = new FileCommand();
                    command.cmd = FileCommand.VOIP_COMMAND_REFUSE;
                    command.channelID = cmd.channelID;
                    var refuseMsg = {};
                    refuseMsg.sender = msg.receiver;
                    refuseMsg.receiver = msg.sender;
                    refuseMsg.content = JSON.stringify({file:command.toData()});
                    this.im.sendRTMessage(refuseMsg);
                }

                this.openFileReceiveWindow(uid, msg.sender, gobelieveToken, cmd.channelID, false, undefined, cmd.name, cmd.size);
            }
        }
    },

    handleNotification(notification) {
        console.log("notification:", notification);
        var obj = JSON.parse(notification);
        if (obj.sync) {
            var sk = obj.sync.sync_key;
            var syncKey = 0;
            if (this.syncKeys && this.syncKeys.contactSyncKey) {
                syncKey = this.syncKeys.contactSyncKey;
            }
            if (sk != syncKey) {
                this.syncContacts();
            }
        }
    },

    // 保存消息的同步key
    saveSyncKey: function(syncKey) {
        this.syncKeys.messageSyncKey = syncKey;
        storage.set("sync.json", this.syncKeys);
    },
    onConnectState: function (state) {
        if (state == IMService.STATE_CONNECTED) {
            console.log("im connected");
        } else if (state == IMService.STATE_CONNECTING) {
            console.log("im connecting");
        } else if (state == IMService.STATE_CONNECTFAIL) {
            console.log("im connect fail");
        } else if (state == IMService.STATE_UNCONNECTED) {
            console.log("im unconnected");
        }
    },


    openWhiteboardWindow(uid, token, room) {

        if (this.whiteboardWin) {
            return;
        }
        var options = {
            width: 800,
            height: 600,
        };

        var self = this;
        var win = new BrowserWindow(options);

        win.on('closed', () => {
            win = null
            self.whiteboardWin = null;
            console.log("wb window close");
        })
        win.loadURL(`file://${__dirname}/whiteboard/index.html?uid=${uid}&token=${token}&room=${room}`);
        if (DEBUG) {
            win.webContents.openDevTools();
        }
        this.whiteboardWin = win;
    },

    openSettingWindow(uid, token, room) {
        if (this.settingWin) {
            this.settingWin.show();
            return;
        }

        var options = {
            width: 800,
            height: 600,
            resizable:false,
            title:'设置',
            backgroundColor:'#f3f3f3'
        };

        var self = this;
        var win = new BrowserWindow(options);
        win.on('closed', () => {
            win = null
            self.settingWin = null;
            console.log("setting window close");
        })
        win.loadURL(`file://${__dirname}/setting.html`);
        if (DEBUG) {
            win.webContents.openDevTools();
        }
        this.settingWin = win;
    },


    exit: function() {
        storage.remove("sync.json")
               .then(() => {
                   storage.remove('token.json', function() {
                       window.location.assign("login.html");
                   });
               })
    },
    onSetting: function() {
        this.openSettingWindow();
    },
    loginOut:function(){
        var r=confirm("是否退出登录")
        if (r==true) {
            api.logout()
            .then(() => {
                ipc.send('exit');
                // window.close();
            })
            .catch((err) => {
                console.error("logout err:", err);
                ipc.send('exit');
                // window.close();
            });
          }
        else{
            return;
          }
    },
    delMember:function(groupId,memberId){
        var r=confirm("是否移除此成员")
        if (r==true) {
            api.delGroupMember(groupId,memberId).then((data)=>{ 
            // history.go(0);
            })
            $("#main").show();
            $("#group").hide();
        }else{
            return;
        }
    
        
    },
    addGroupMessage:function(){
       $("#main").hide();
       $("#group").hide();
       $("#gMembers").show();
       this.setState({showGroupContact:false,showContact:true,showConversation:false,showUserList:true});
    },
    onContactItemClick(uid) {
        $("#main").show();
        $("#group").hide();
        var users = this.state.contacts;

        var u = users.find((item) => {
            return (item.uid == uid);
        });

        if (!u) {
            return;
        }

        users.forEach((item)=> {
            item.active = false;
        });
        u.active = true;
        this.setState({contact:u});
    },
    onGroupItemClick(gid){
        // console.log($(this))
        var groups=this.state.contactsGroups
       console.log(gid)
        api.getGroup(gid).then((group)=>{
            group.members.forEach((item)=> {
                if (!item.name) {
                    var u = userDB.findUser(item.uid);
                    if (u) {
                        item.name = u.name;
                    }
                }
            })
            $("#main").hide();
            $("#group").show();
            this.setState({groupInfo:group,showGroupContact:true,showContact:true,showConversation:false,showUserList:false});
        })
        
    },
    onSystemItemClick:function(system,states){
        if(states == 0){
            api.newFriends(system.new_friends.id,0)
        }else{
            api.newFriends(system.new_friends.id,1)
        }   
         this.stytemDB.remove();
        history.go(0);
    },
    onConversationClick(conv) {
        console.log("click conv:", conv);
        var self = this;
        if (conv.type == CONVERSATION_GROUP) {
            this.groupDB.findGroup(conv.groupID)
                        .then((group) => {
                            console.log("group:", conv.groupID, " members:",  group.members);
                            group.members.forEach((item)=> {
                                if (!item.name) {
                                    var u = userDB.findUser(item.uid);
                                    if (u) {
                                        item.name = u.name;
                                    }
                                }
                            })
                            this.setState({group:group});
                        });

            if (conv.dirty) {
                //更新群组信息
                api.getGroup(conv.groupID)
                    .then((group) => {
                        console.log("add group:", group);
                        self.groupDB.addGroup(group);
                        var action = {
                            type:"set_conversation_name", 
                            name:group.name, 
                            lvl:group.lvl,
                            avatar:group.portrait, 
                            cid:conv.cid, 
                        };
                        self.props.dispatch(action);
                        self.props.dispatch({type:"set_conversation_dirty", cid:conv.cid, dirty:false});
                        self.setState({group:group});
                    })
                    .catch((err) => {
                        console.log("get group err:", err);
                    });
            }
        }

        this.props.dispatch({type:"set_conversation", conversation:conv});
        this.props.dispatch({type:"set_unread", unread:0, cid:conv.cid});
        this.conversationDB.setNewCount(conv.cid, 0);
        var total = 0;
        for (var i = 0; i < this.props.conversations.length; i++) {
            if (this.props.conversations[i].cid != conv.cid) {
                total = total + this.props.conversations[i].unread;
            }
        }

        setDockBadge(total);
    },

    onSendMessage:function() {
        console.log("on send message");
        var uid = this.state.contact.uid;
        var cid = "peer_" + uid;

        var index = -1;
        for (var i = 0; i < this.props.conversations.length; i++) {
            var conv = this.props.conversations[i];
            if (conv.cid == cid) {
                index = i;
                break;
            }
        }
        var conv;
        if (index == -1) {
            var name = this.state.contact.name || this.state.contact.uid;
            conv = {
                type:CONVERSATION_PEER,
                peer:this.state.contact.uid,
                cid:"peer_" + this.state.contact.uid,
                name:name,
                avatar:this.state.contact.avatar,
                unread:0,
            };

            this.conversationDB.addConversation(conv);
            this.props.dispatch({type:"add_conversation", conversation:conv});
        } else {
            conv = this.props.conversations[index];
        }

        this.props.dispatch({type:"set_conversation", conversation:conv});
        this.props.dispatch({type:"set_unread", unread:0, cid:conv.cid});
        this.conversationDB.setNewCount(conv.cid, 0);
        var total = 0;
        for (var i = 0; i < this.props.conversations.length; i++) {
            total = total + this.props.conversations[i].unread;
        }

        setDockBadge(total);

        this.setState({
            showConversation:true,
            showContact:false,
            showGroupContact:false,
            showUserList:false
        });
    },
    onSendGroupMessage(){
        var id = this.state.groupInfo.id;
        var cid = "group_" + id;
        var index = -1;
        for (var i = 0; i < this.props.conversations.length; i++) {
            var conv = this.props.conversations[i];
            if (conv.cid == cid) {
                index = i;
                break;
            }
        }
        var conv;
        if (index == -1) {
            var name = this.state.groupInfo.name || this.state.groupInfo.id;
            conv = {
                type:CONVERSATION_GROUP,
                group:this.state.groupInfo.id,
                groupID:id,
                cid: "group_" +this.state.groupInfo.id,
                name:name,
                lvl:this.state.groupInfo.lvl,
                avatar:this.state.groupInfo.portrait,
                unread:0,
            };
            this.conversationDB.addConversation(conv);
            this.props.dispatch({type:"add_conversation", conversation:conv});
        } else {
            conv = this.props.conversations[index];
        }
        this.props.dispatch({type:"set_conversation", conversation:conv});
        this.props.dispatch({type:"set_unread", unread:0, cid:conv.cid});
        this.conversationDB.setNewCount(conv.cid, 0);
        var total = 0;
        for (var i = 0; i < this.props.conversations.length; i++) {
            total = total + this.props.conversations[i].unread;
        }
        setDockBadge(total);
        this.setState({
            showConversation:true,
            showContact:false,
            showGroupContact:false,
            showUserList:false
        });
    },
    addGroupMember:function(groupId){
        var id=[];
        $(".usersList input:checkbox[name='multiple']:checked").each(function(){
            id.push($(this).attr("data-uid"))
        });
        if(id.length>0){
            api.addGroupMembers(groupId,id)
        }else{
            // dialog.showErrorBox("请选择好友");
        }
        $("#main").show();
        $("#group").hide();
        $("#gMembers").hide();
    },
    quitGroup:function(groupId){
        console.log(groupId);
        var id="group_"+groupId
        var r=confirm("是否退出群聊")
        if(r==true){
            api.quitGroup(groupId)
            history.go(0);
            this.deleteConversation(id)
        }else{
            return false;
        }
    },
    delGroup:function(groupId){
        var id="group_"+groupId
        var r=confirm("是否解散群聊")
        if (r==true) {
            // api.delGroup(groupId);
            this.deleteConversation(id)
            history.go(0);
        }else{
            return false;
        }
       
    },
    deleteConversation: function(cid) {
        // var self=this
        // for(var i=0;i<this.props.conversations.length;i++){
        //     if (this.props.conversations[i].cid == cid) {
        //         this.props.dispatch({type:"set_conversation", conversation:{}});
        //     }
        // }
        if (this.props.conversation.cid == cid) {
            this.props.dispatch({type:"set_conversation", conversation:{}});
        }
        this.props.dispatch({type:"remove_conversation", cid:cid});
        this.conversationDB.removeConversation(cid);
    },
    //截屏
    onClipboard:function() {
        this.startCapture();
    },

    onContactClick: function() {
        console.log("show contact");
        $("#main").show();
        $("#group").hide();
        this.setState({showContact:true, showConversation:false,showGroupContact:false,showUserList:false});
    },

    onMessageClick: function() {
        this.setState({showContact:false, showConversation:true,showGroupContact:false,showUserList:false});
    },

    onFileChange: function(filePath) {
        if (!filePath) {
            return;
        }
        console.log("file:", filePath);
        var stat = fs.statSync(filePath);
        var size = stat.size;

        if (size > FILE_LIMIT && this.props.conversation.type != CONVERSATION_PEER) {
            var limit = Math.floor(FILE_LIMIT/(1024*1024))
            alert("文件大小不能超过" + limit + "M");
            return;
        }

        if (this.props.conversation.type == CONVERSATION_PEER) {
            var name = this.props.conversation.name;
            var fileName = path.basename(filePath);
            var options = {
                message:`是否要发送文件${fileName}给${name}`,
                buttons:["确定", "取消"],
                defaultId:0,
                cancelId:1
            };
            var self = this;
            var win = remote.getCurrentWindow();
            dialog.showMessageBox(win, options, function(response) {
                if (response == 1) {
                    return;
                }
                if (size <= FILE_LIMIT) {
                    self.sendFileMessage(filePath, size);
                } else {
                    //p2p方式发送文件
                    var uid = self.props.loginUser.uid;
                    var peer = self.props.conversation.peer;
                    var gobelieveToken = self.props.loginUser.gobelieveToken;
                    var channelID = uuidv1();
                    var fileName = path.basename(filePath);
                    self.openFileWindow(uid, peer, gobelieveToken, channelID, true, filePath, fileName, size);
                }
            });
        } else if (this.props.conversation.type == CONVERSATION_GROUP){
            var name = this.props.conversation.name;
            var fileName = path.basename(filePath);
            var options = {
                message:`是否要发送文件${fileName}到群组${name}`,
                buttons:["确定", "取消"],
                defaultId:0,
                cancelId:1
            };
            var self = this;
            var win = remote.getCurrentWindow();
            dialog.showMessageBox(win, options, function(response) {
                if (response == 1) {
                    return;
                }
                self.sendFileMessage(filePath, size);
            });
        }
    },

    onImageChange: function(filePath, fileBlob) {
        var f;
        if (filePath) {
            var ext = path.extname(filePath)
            if (ext != '.png' && ext != '.jpg' && ext != '.jpeg') {
                return;
            }
            var data = fs.readFileSync(filePath);
            var b = new Blob([data])
            f = new File([b], filePath);
        } else if (fileBlob) {
            f = fileBlob;
        } else {
            return;
        }

        this.setState({
            showPreview:true,
            preview:{},
        });

        var self = this;

        var reader = new FileReader();
        reader.onload = function (e) {
            var src = e.target.result;
            var maxWidth = 1024;
            var maxHeight = 1024;
            var img = new Image();
            img.onload = function () {
                var canvas = document.createElement('canvas');
                if (img.height > maxHeight) {
                    img.width = maxHeight / img.height * img.width;
                    img.height = maxHeight;
                }
                var ctx = canvas.getContext('2d');
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                canvas.width = img.width;
                canvas.height = img.height;
                ctx.drawImage(img, 0, 0, img.width, img.height);
                var preview = canvas.toDataURL('image/jpeg');
                self.setState({preview:{url:preview, width:img.width, height:img.height}});
            };
            img.src = src;
        };
        reader.readAsDataURL(f);
    },

    onAudioVOIP: function() {
        if (this.props.conversation.type == CONVERSATION_PEER) {
            var uid = this.props.loginUser.uid;
            var peer = this.props.conversation.peer;
            var gobelieveToken = this.props.loginUser.gobelieveToken;
            var accessToken = this.props.loginUser.accessToken;
            var channelID = uuidv1();
            this.openVOIPWindow(uid, peer, gobelieveToken, accessToken, channelID, true, false);
        }
    },

    onVideoVOIP: function() {
        if (this.props.conversation.type == CONVERSATION_PEER) {
            var uid = this.props.loginUser.uid;
            var peer = this.props.conversation.peer;
            var gobelieveToken = this.props.loginUser.gobelieveToken;
            var accessToken = this.props.loginUser.accessToken;
            var channelID = uuidv1();
            this.openVOIPWindow(uid, peer, gobelieveToken, accessToken, channelID, true, true);
        } else {
            //group
            if (!this.state.group) {
                return;
            }

            var uid = parseInt(this.props.loginUser.uid);
            var name = this.props.loginUser.name;
            var channelID = uuidv1();
            var gobelieveToken = this.props.loginUser.gobelieveToken;
            var groupID = this.props.conversation.groupID;
            var participants = this.state.group.members.map(function(p) {
                return p.uid;
            });

            this.openGroupCallWindow(uid, name, gobelieveToken, channelID, uid, participants, groupID);
        }
    },

    //取消文件上传
    onUploadCancel: function(msg) {
        var cid = this.props.conversation.cid;
        var obj = this.uploadingMessages.find(function(item) {
            return (item.cid == cid && msg.msgLocalID == item.msgLocalID);
        });
        if (!obj) {
            return;
        }
        console.log("abort:", msg);
        obj.request.unsubscribe();
        this.removeUploadRequest(obj);
        if (this.props.conversation.type == CONVERSATION_PEER) {
            this.imDB.setCanceled(msg.msgLocalID, true);
        } else if (this.props.conversation.type == CONVERSATION_GROUP) {
            this.groupMessageDB.setCanceled(msg.msgLocalID, true);
        }
    },

    onInfoClick: function(e) {
        e.stopPropagation();
    },

    onInfoAnimationEnd() {
        console.log("on animation end");
        if (!this.state.showInfo) {
            this.setState({showInfo:undefined});
        }
    },

    onDragEnter(event) {
        document.getElementById("entry").blur();
        console.log("drag enter:", event, event.dataTransfer.files, event.dataTransfer.types, event.dataTransfer.items);
        if (event.dataTransfer.types && event.dataTransfer.types.includes("Files")) {
            this.setState({inDrag:this.state.inDrag+1});
        }
        //todo check (event.dataTransfer.types.length != 0 && event.dataTransfer.types[0] == "Files") {
        event.preventDefault();
        event.stopPropagation();
    },

    onDragLeave(event){
        if (event.dataTransfer.types && event.dataTransfer.types.includes("Files")) {
            this.setState({inDrag:this.state.inDrag-1});
        }
        event.preventDefault();
        event.stopPropagation();
    },

    onDragOver(event) {
        event.preventDefault();
        event.stopPropagation();
        //console.log("drag over event:", event);
    },

    onDrop(event) {
        this.setState({inDrag:0});
        event.preventDefault();
        event.stopPropagation();
        console.log("drop event:", event, event.dataTransfer.files);
    },

    onDragEnter2(event) {
        this.setState({inDrag:this.state.inDrag+1});
        event.preventDefault();
        event.stopPropagation();
    },
    onDragLeave2(event){
        this.setState({inDrag:this.state.inDrag-1});
        event.preventDefault();
        event.stopPropagation();
    },

    onDragOver2(event) {
        event.preventDefault();
        event.stopPropagation();
        console.log("drag over event:", event);
    },

    onDrop2(event) {
        this.setState({inDrag:0});
        event.preventDefault();
        event.stopPropagation();
        console.log("drop event:", event, event.dataTransfer.files);
        if (event.dataTransfer.files.length == 0) {
            return;
        }
        var f = event.dataTransfer.files[0];
        var filePath = f.path;
        var ext = path.extname(filePath)

        if (ext != '.png' && ext != '.jpg' && ext != '.jpeg') {
            //file
            this.onFileChange(filePath);
        } else {
            this.onImageChange(filePath);
        }
    },


    renderGroup() {
        var group = this.state.group;
        if (!group) {
            return;
        }
        console.log("group:", group);

        var infoCls = ""
        if (this.state.showInfo == undefined) {
            infoCls = "";
        } else if (this.state.showInfo){
            infoCls = "show";
        } else {
            infoCls = "disappear";
        }

        var members =  group.members.map(function(item) {
                        return (
                            <div key={item.uid} className="member">
                                <img className="avatar" src={item.avatar ? item.avatar : "./images/_avatar.png"}></img>
                                <p>{item.name}</p>
                            </div>
                        );
                    });

        return (
            <div
                onClick={this.onInfoClick}
                onAnimationEnd={this.onInfoAnimationEnd}
                className={"info " + infoCls}>
                {members}
            </div>
        )
    },

    renderMessage: function() {
        var name = this.props.conversation.name;
        var avatar = this.props.conversation.avatar;

        if (!avatar) {
            var conv = this.props.conversation;
            if (conv.type == CONVERSATION_PEER) {
                avatar = "images/_avatar.png";
            } else if (conv.type == CONVERSATION_GROUP) {
                avatar = "images/avatar_group.png";
            }
        }
        var hideAudioVOIP = (this.props.conversation.type != CONVERSATION_PEER);
        var hideVideoVOIP = !DEBUG;
        return (
            <div className="main pane-chat" id="main">

                <div className={"intro" + (this.props.conversation.cid ? " hide" : "")} id="intro">
                    请选择联系人
                </div>

                <div className="pane-header">
                    <div className="name" id="to_user">{name}</div>
                    {(this.props.conversation.type == CONVERSATION_GROUP) ? <div className="info-button"  onClick={this.onInfo}></div> : null }
                </div>

                <div onDragOver={this.onDragOver}
                    onDrop={this.onDrop}
                    onDragLeave={this.onDragLeave}
                    onDragEnter={this.onDragEnter}
                    className="chat-area">
                    <ChatHistory ref={(chat) => { this.chat = chat; }}
                                 uptime={this.uptime}
                                 imDB={this.imDB}
                                 groupDB={this.groupMessageDB}
                                 userDB={userDB}
                                 uploadingMessages={this.uploadingMessages}
                                 openVideoWindow={this.openVideoWindow}
                                 cancelUploadFile={this.onUploadCancel}/>

                    <InputBar
                        ref={(input) => { this.inputBar = input; }}
                        hideAudioVOIP={hideAudioVOIP}
                        hideVideoVOIP={hideVideoVOIP}
                        onImageChange={this.onImageChange}
                        onClipboard={this.onClipboard}
                        onFileChange={this.onFileChange}
                        onAudioVOIP={this.onAudioVOIP}
                        onVideoVOIP={this.onVideoVOIP}
                        sendTextMessage={this.sendTextMessage} />
                    {this.renderGroup()}
                    <div onDragOver={this.onDragOver2}
                        onDrop={this.onDrop2}
                        onDragLeave={this.onDragLeave2}
                        onDragEnter={this.onDragEnter2}
                        className={"drop-area" + (this.state.inDrag ? " in-drag":"")}>发送文件</div>
                </div>
            </div>
        );
    },

    renderContact: function() {
        // console.log("this.state.contact+++++"+JSON.stringify(this.state.contact))
        var avatar = this.state.contact.avatar;
        if (!avatar) {
            avatar = "images/_avatar.png";
        }

        return (
            <div className="main pane pane-chat" id="main">

                <div className={"intro" + (this.state.contact.uid ? " hide" : "")} id="intro">
                    请选择联系人
                </div>

                <div className="contact">
                    <div className="header">
                        <span>{this.state.contact.name}</span>
                        <img src={avatar} className="avatar"/>
                    </div>
                    <div className="line">
                    </div>

                    <div className="item">
                        <p>轻言号：<span>{this.state.contact.account}</span></p>
                        {/* <p>备注名：<input  type="text" defaultValue={this.state.contact.nickname}/><span>确定</span></p> */}
                    </div>
                    <button className="" onClick={this.onSendMessage}>发消息</button>
                </div>
            </div>
        );
    },
    addRenderGroupMembers: function() {
        var users = this.state.contacts;
        var group=this.state.groupInfo;
        var userList=[];
        for(var i=0;i<users.length;i++){
            var bool=false;
            for (var j=0;j<group.members.length;j++){
                if(users[i].id == group.members[j].id){
                    bool=true;
                }
            }
            var img=users[i].portrait
            if(!img){
                img="images/_avatar.png"
            }
            var g=(
                <li
                key={users[i].id}>
                    <div className="groupMem">
                    <input type="checkbox" disabled={bool} defaultChecked={bool ? "true":""} name="multiple" data-uid={users[i].id}/>
                    <img src={img} className="avatar" alt=""/>
                    <span>{users[i].name}</span>
                    </div>
                </li>
            )
            userList.push(g)
        }
        return (
            <div className="main pane pane-chat" id="gMembers">
            <div className="" id="intro">
                </div>
                <div className="contact">
                <div className="header">
                添加群成员
                
                    </div>
                    <div className="line">
                    </div>
                <div className="item">
                        <ul className="usersList">
                           {userList}
                        </ul>
                </div>
                <button className="" onClick={this.addGroupMember.bind(this,group.id)}>确定</button>
                </div>
            </div>
        );
    },
    renderGroupContact: function() {
        // console.log("this.state.contact+++++"+JSON.stringify(this.state.contact))
        var group = this.state.groupInfo
        var info = this.state.info
        var groupMembers=[];
        var str="";
        // console.log("this.state.groupInfo+显示"+JSON.stringify(this.state.groupInfo))
        var avatar = group.portrait;
        if (!avatar) {
            avatar = "images/avatar_group.png";
        }
        // $(".quitGroup").hide();
       
        var role=false;
        var st;
        var display="none";
        for(var i=0;i<group.members.length;i++){
            if(group.members[i].role == "1"){
                if(info.id == group.members[i].id){
                role=true;
                }
            }
        }
        if(role == false){
           st={
                textAlign: 'center',
                backgroundColor: '#63b74e',
                width: '120px',
                height: '36px',
                margin: 'auto',
                lineHeight: '36px',
                borderRadius: '6px',
                marginTop: '10px',
                fontSize: '12px'
            }
        }else{
            st={}
        }
        for(var i=0;i<group.members.length;i++){
        var img=group.members[i].portrait;
        if(!img){
            img="images/_avatar.png"
        }
        var g=(
            <li data-uid={group.members[i].id}
                key={group.members[i].id}>
                <div className="groupMem">
                <img src={img} style={{borderRadius:"4px"}} className="avatar" alt=""/>
                <span>{group.members[i].name}</span>
                <span style={{cursor:"pointer"}} onClick={this.delMember.bind(this,group.id,group.members[i].id)}>{role && info.id != group.members[i].id ? "移除" : ""}</span>
                </div>
            </li>
        )
        groupMembers.push(g)
        }
        return (
            <div className="main pane pane-chat" id="group">

                <div className={"intro" + (group.id ? " hide" : "")} id="intro">
                    请选择群组
                </div>

                <div className="contact">
                    <div className="header">
                        <span>{group.name}</span>
                        <img src={avatar} className="avatar"/>
                        <span className=""  style={{cursor:"pointer",paddingLeft:"20px"}}  onClick={this.delGroup.bind(this,group.id)}>{role ? "解散群" : ""}</span>
                    </div>
                        {/* <p>群公告:{group.bulletin ?  group.bulletin : ""}</p> */}
                    <div className="line">
                    </div>
                    <div  style={{margin:"auto"}}>
                        <button className="" style={{marginTop:"10px",cursor:"pointer"}} onClick={this.addGroupMessage}>添加群成员</button>
                        </div>
                    <div className="item">
                        <ul>
                           {groupMembers}
                        </ul>
                    </div>
                    <button className="" onClick={this.onSendGroupMessage}>发消息</button>
                    <p className="quitGroup" style={st} onClick={this.quitGroup.bind(this,group.id)}>{role ? "" : "退出群聊"}</p>
                </div>
            </div>
        );
    },
    renderBar: function() {
        var c1 = this.state.showConversation ? "LeftNav-item iconfont-single cur" : "LeftNav-item iconfont-single";
        var c2 = this.state.showContact ? "LeftNav-item iconfont-group cur": "LeftNav-item iconfont-group";
        return (
            <div className="toolbar">
                <div className="LeftNav">
                    <div className={c1}
                         onClick={this.onMessageClick}>
                        <div className="singleChat">
                            <a>single chat</a>
                        </div>
                    </div>
                    <div className={c2}
                         onClick={this.onContactClick}>
                        <div className="groupChat">
                            <a>group chat</a>
                        </div>
                    </div>
                    <p className="loginOut" onClick={this.loginOut}>
                        退出登录
                    </p>
                    <p className="setting" onClick={this.onSetting}>
                        设置
                    </p>
                </div>
            </div>
        );
    },

    onInfo: function(e) {
        e.stopPropagation();
        var showInfo = !this.state.showInfo;
        this.setState({showInfo:showInfo});
    },

    onCancel: function() {
        this.setState({
            showPreview:false,
            preview:{},
        });
    },

    onSend: function() {
        var b64 = this.state.preview.url;
        if (b64) {
            this.sendImageMessage(b64, this.state.preview.width, this.state.preview.height);
        }
        this.setState({
            showPreview:false,
            preview:{},
        });
    },

    renderPreview: function() {
        var loading = !this.state.preview.url;
        var display = loading ? "inline-block" : "none";
        return (
            <div>
                <div className="previewPicLayer"></div>
                <div className="previewPic" tabIndex="1">
                    <span className="closeBtn"
                          onClick={this.onCancel}></span>
                    <h2>发送图片</h2>
                    <div className="picWrap">
                        <img className="picContent" src={this.state.preview.url} alt=""/>
                    </div>
                    <div className="picFooter">
                        <button type="button"
                                className="btn"
                                onClick={this.onCancel}>
                            取消
                        </button>
                        <button type="button"
                                className="btn cur"
                                onClick={this.onSend}>
                            发送
                        </button>
                    </div>
                </div>
                <div className="load-container" style={{display:display}}>
                    <div className="loader">Loading...</div>
                </div>
            </div>
        );
    },

    onDocumentClick: function(event) {
        if (event.target.tagName === 'A' && event.target.href.startsWith('http')) {
            event.preventDefault()
            shell.openExternal(event.target.href)
            return;
        }

        console.log("document on click:", this.state.showInfo);

        if (this.state.showInfo) {
            this.setState({showInfo:false});
        }
        if (this.inputBar) {
            this.inputBar.hideEmoji();
        }
    },

    render: function() {
        return (
            <div onClick={this.onDocumentClick}
                 className="app">
                {this.renderBar()}
                <div className="pane-list">
                    {this.state.showConversation ?
                     <ConversationList
                         onConversationClick={this.onConversationClick}
                         conversationDB = {this.conversationDB}
                         imDB={this.imDB}
                         groupDB={this.groupMessageDB}/> : null}
                     {this.state.showContact ?
                      <ContactList contacts={this.state.contacts}
                      systemMessage={this.state.systemMessage}
                      contactsGroups={this.state.contactsGroups}
                      onGroupClick={this.onGroupItemClick}
                      onSystemClick={this.onSystemItemClick}
                                   onContactClick={this.onContactItemClick} /> : null}

                </div>

                {this.state.showConversation ? this.renderMessage() : null}
                {this.state.showContact ? this.renderContact(): null}
                {this.state.showGroupContact ? this.renderGroupContact() : null}
                {this.state.showPreview ? this.renderPreview(): null}
                {this.state.showUserList ? this.addRenderGroupMembers(): null}
            </div>
        );
    }
});


AppContent = connect(function(state){
    return state;
}, null, null, {withRef:true})(AppContent);


module.exports = AppContent;
